import tkinter as tk  # 导入 tkinter 库，用于创建 GUI 界面，并简称为 tk
import tkinter.messagebox  # 导入 tkinter 的 messagebox 模块，用于显示消息框
import pickle  # 导入 pickle 模块，用于序列化和反序列化 Python 对象结构
import random  # 导入 random 模块，用于生成随机数
from PIL import Image, ImageTk  # 从 PIL (Pillow) 库中导入 Image 和 ImageTk 模块，用于在 Tkinter 中显示图片

def 生成验证码():
    """生成一个六位数的随机验证码，包含大小写字母和数字。"""
    验证码字符列表 = ''  # 初始化一个空字符串，用于存储生成的验证码
    for _ in range(6):  # 循环生成六位验证码
        类型选择 = random.randint(1, 3)  # 随机选择验证码字符的类型：1-大写字母, 2-小写字母, 3-数字
        if 类型选择 == 1:  # 如果选择类型1
            大写字母ASCII = random.randint(65, 90)  # 生成一个大写字母的 ASCII 码 (A-Z)
            验证码字符列表 += chr(大写字母ASCII)  # 将生成的字符追加到验证码字符串
        elif 类型选择 == 2:  # 如果选择类型2
            小写字母ASCII = random.randint(97, 122)  # 生成一个小写字母的 ASCII 码 (a-z)
            验证码字符列表 += chr(小写字母ASCII)  # 将生成的字符追加到验证码字符串
        else:  # 如果选择类型3
            验证码字符列表 += str(random.randint(0, 9))  # 生成一个 0-9 之间的随机数字并追加到验证码字符串
    return 验证码字符列表  # 返回生成的六位验证码字符串

# 全局变量，存储当前生成的验证码值
当前验证码 = 生成验证码()  # 调用函数生成一个验证码，并存储在全局变量中

# --- 主窗口设置 ---
主窗口 = tk.Tk()  # 创建 Tkinter 主窗口实例
主窗口.title('图书管理系统')  # 设置主窗口的标题
主窗口.geometry('450x300')  # 设置主窗口的尺寸（宽度x高度）
主窗口.resizable(width=False, height=False)  # 设置主窗口大小不可调整

# --- 背景图片设置 ---
画布 = tk.Canvas(主窗口, height=300, width=500)  # 在主窗口上创建一个画布，用于放置图片
img = Image.open('背景.png')  # 打开背景图片
背景图片文件 = ImageTk.PhotoImage(img)  # 加载背景图片
画布.create_image(0, 0, anchor='nw', image=背景图片文件)  # 在画布上放置图片
画布.image = 背景图片文件  # 保持图片引用
画布.pack(side='top')  # 将画布放置在主窗口的顶部

# --- 标签和输入框 ---
# 用户名标签和输入框
tk.Label(主窗口, text='用户名:').place(x=100, y=110)
用户名输入变量 = tk.StringVar()
用户名输入框 = tk.Entry(主窗口, textvariable=用户名输入变量)
用户名输入框.place(x=160, y=110)

# 密码标签和输入框
tk.Label(主窗口, text='密   码:').place(x=100, y=150)
密码输入变量 = tk.StringVar()
密码输入框 = tk.Entry(主窗口, textvariable=密码输入变量, show='*')
密码输入框.place(x=160, y=150)

# 验证码标签和输入框
tk.Label(主窗口, text='验证码:').place(x=100, y=190)
验证码标签 = tk.Label(主窗口, text=当前验证码)
验证码标签.place(x=310, y=190)
验证码输入变量 = tk.StringVar()
验证码输入框 = tk.Entry(主窗口, textvariable=验证码输入变量)
验证码输入框.place(x=160, y=190)

# --- 用户信息存储文件名 ---
用户信息文件 = 'usr_info.pickle'

def 用户登录():
    """处理用户登录逻辑。"""
    global 当前验证码
    # 获取用户输入
    输入用户名 = 用户名输入变量.get()
    输入密码 = 密码输入变量.get()
    输入验证码 = 验证码输入变量.get()

    # 加载用户信息
    if not 输入用户名 or not 输入密码:
        tkinter.messagebox.showerror(title='错误', message='用户名或密码不能为空')
        return

    # 读取或创建用户信息文件
    用户信息字典 = {}
    with open(用户信息文件, 'rb') as 文件对象:
        用户信息字典 = pickle.load(文件对象)

    # 校验登录信息
    if 输入用户名 in 用户信息字典:
        if 输入密码 == 用户信息字典[输入用户名]:
            if 输入验证码 == 当前验证码:
                tkinter.messagebox.showinfo(title='欢迎', message=f'欢迎您：{输入用户名}')
            else:
                tkinter.messagebox.showerror(title='错误', message='验证码错误')
                当前验证码 = 生成验证码()
                验证码标签.config(text=当前验证码)
        else:
            tkinter.messagebox.showerror(title='错误', message='密码错误')
    else:
        是否注册 = tkinter.messagebox.askyesno('提示', '您还没有注册，是否现在注册？')
        if 是否注册:
            用户注册()

def 用户注册():
    """处理用户注册逻辑，并打开注册窗口。"""
    def 执行注册():
        """在注册窗口中点击"确认注册"按钮时执行的函数。"""
        # 获取注册窗口中的输入
        新用户名 = 新用户名输入变量.get()
        新密码 = 新密码输入变量.get()
        确认密码 = 确认密码输入变量.get()

        # 加载已有的用户信息
        已存在用户信息 = {}
        with open(用户信息文件, 'rb') as 文件对象:
            已存在用户信息 = pickle.load(文件对象)

        # 校验注册信息
        if not 新用户名 or not 新密码:
            tkinter.messagebox.showerror('错误', '用户名或密码不能为空', parent=注册窗口)
            return

        if 新用户名 in 已存在用户信息:
            tkinter.messagebox.showerror('错误', '用户名已存在', parent=注册窗口)
        elif 新密码 != 确认密码:
            tkinter.messagebox.showerror('错误', '两次输入的密码不一致', parent=注册窗口)
        else:
            已存在用户信息[新用户名] = 新密码
            with open(用户信息文件, 'wb') as 文件对象:
                pickle.dump(已存在用户信息, 文件对象)
            tkinter.messagebox.showinfo('成功', '注册成功！', parent=注册窗口)
            注册窗口.destroy()

    # --- 注册窗口设置 ---
    注册窗口 = tk.Toplevel(主窗口)
    注册窗口.geometry('350x200')
    注册窗口.title('用户注册')
    注册窗口.resizable(width=False, height=False)

    # --- 注册窗口的标签和输入框 ---
    新用户名输入变量 = tk.StringVar()
    tk.Label(注册窗口, text='用户名：').place(x=30, y=20)
    tk.Entry(注册窗口, textvariable=新用户名输入变量).place(x=130, y=20)

    新密码输入变量 = tk.StringVar()
    tk.Label(注册窗口, text='输入密码：').place(x=30, y=60)
    tk.Entry(注册窗口, textvariable=新密码输入变量, show='*').place(x=130, y=60)

    确认密码输入变量 = tk.StringVar()
    tk.Label(注册窗口, text='确认密码：').place(x=30, y=100)
    tk.Entry(注册窗口, textvariable=确认密码输入变量, show='*').place(x=130, y=100)

    确认注册按钮 = tk.Button(注册窗口, text='确认注册', command=执行注册)
    确认注册按钮.place(x=150, y=140)

    注册窗口.grab_set()
    注册窗口.wait_window()

def 用户退出():
    """关闭主应用程序窗口。"""
    主窗口.destroy()

# --- 主窗口按钮 ---
登录按钮 = tk.Button(主窗口, text='登录', command=用户登录)
登录按钮.place(x=140, y=230)

注册按钮 = tk.Button(主窗口, text='注册', command=用户注册)
注册按钮.place(x=210, y=230)

退出按钮 = tk.Button(主窗口, text='退出', command=用户退出)
退出按钮.place(x=280, y=230)

# --- 启动 Tkinter 事件循环 ---
主窗口.mainloop()
